/* Using Node.js to test the CodePlex HTTP API
 * Requires: Node.js from http://nodejs.org/
 *           Request -- Simplified HTTP client by mikeal from https://github.com/mikeal/request (npm install request)
 * 
 * Usage: Set node_host and node_port if necessary
 *        Configure client_secret, client_id, and state
 *        node CodePlex_ApiSample.js
 *        Browse to http://<node_host>:<node_port>
 */


// node settings
var node_host = "localhost";
var node_port = "8081";

// app settings
var client_id = "<YOUR_APP_CLIENT_ID>";
var client_secret = "<YOUR_APP_CLIENT_SECRET>";
var state = "<SOME_RANDOM_STRING>";


// ------------------------------------------------------------
// Don't change anything below here unless you know what you're doing!
// ------------------------------------------------------------

// dependences
var http = require("http");
var url = require("url");
var requestClient = require('request');

// url setup and routing
var node_uri = "http://" + node_host + ":" + node_port;
var redirect_uri =  node_uri + "/response";
var init_path = "start";
var response_path = "response";

// codeplex variables
var codeplex_domain = "https://www.codeplex.com"
var auth_url = codeplex_domain + "/oauth/authorize";
var token_url = codeplex_domain  + "/oauth/token";
var user_url = codeplex_domain + "/api/user";
var projects_url = codeplex_domain + "/api/user/projects";

http.createServer(function(request, response) {

    var code;
    
    // use request URL for rudimentary routing
    var theUrl = url.parse(request.url, true)
  
    // homepage with a "Start" button
    if (theUrl.pathname.length === 1)
    {
        WriteHeader();
        response.write('<h2>CodePlex API Example</h2>');
        response.write('<form name="input" action="' + node_uri + '/' + init_path + '" method="GET"><input type="submit" value="Start"></form>');
        response.end();
    }
  
    // start auth flow
    else if (theUrl.pathname.indexOf(init_path) === 1)
    {
        response.writeHead(302,
          { 
            "Location" : auth_url + "?" + 
            "client_id=" + client_id + "&" + 
            "state=" + state + "&" +
            "response_type=code" + "&" + 
            "redirect_uri=" + redirect_uri
          }
        );
        response.end();
    }
  
    // parse response
    else if (theUrl.pathname.indexOf(response_path) === 1)
    {
        WriteHeader();
        response.write('<h2>Step 1 & Step 2 Response:</h2>');
        response.write('<pre>');
        
        // get code response
        for (var key in theUrl.query)
        {
            response.write(key + ": " + theUrl.query[key] + '\n');
        }
        
        response.write('</pre>');

        code = theUrl.query['code'];
        
        // send POST for token
        requestClient.post(
            token_url,
            { form: 
                { 
                    'client_id' : client_id,  
                    'client_secret': client_secret,
                    'code': code,
                    'state': state,
                    'redirect_uri': redirect_uri,
                    'grant_type' : 'authorization_code'
                }
            },
            // output response
            function (e, r, body) {
                response.write('<h2>Step 3 Response:</h2>');
                if (!e && r.statusCode == 200) 
                {
                    GotAccessToken_ApiTest(JSON.parse(body));
                }
                else
                {
                    GotAccessToken_ApiTest("INVALID");
                }
            }
        );
    }
    
    // use the returned token to do something
    function GotAccessToken_ApiTest(token_response)
    {
        if (token_response != "INVALID")
        {
            response.write('<pre>');
            
            for (var key in token_response)
            {
                response.write(key + ": " + token_response[key] + '\n');
            }
            
            response.write('</pre>');
            
            var token = token_response['access_token'];
        
            response.write('<h2>Using Step 4 with the API:</h2>');

            // test user API
            WriteApiResponse(user_url, token, true);
        }
    }
    
    
    // hit api at uri with token
    function WriteApiResponse(url, token, end)
    {
        response.write('<pre>');
        requestClient.get(
            url,
            { headers: { 'Authorization': 'Bearer ' + token } },
            function(e, r, body)
            {
                var parsed = JSON.parse(body);
                for (var key in parsed)
                {
                    response.write(key + ': ' + parsed[key] + '\n'); 
                }
                
                response.write('</pre>');
                if (end)
                {
                    response.write('</body></html>');
                    response.end();
                }
            }
        );
    }
    
    function WriteHeader()
    {
        response.writeHead(200, {"Content-Type": "text/html"});
        response.write('<!doctype html><html><head><title>CodePlex API Test</title></head><body>');
    }

}).listen(node_port, node_host);

console.log('Server is listening on ' + node_uri);